package com.just.fun.thread;

import java.util.concurrent.CountDownLatch;

/**
 * 线程同步，要扣原理
 */
public class ThreadSync {
    public static void main(String[] args) throws Exception{
       //method1();
        method2();
    }


    /**
     * 利用join方法
     * 原理：
     * 核心代码：
     * while (isAlive()) {        //调用join方法线程是运行时状态
     *       wait(0);             //进入等待
     *  }
     *  join方法本质就是利用调用的线程实例作为对象锁的原理，当线程终止时，会调用线程自身的notifyAll()方法，通知所有等待在该线程对象上的线程的特征
     *  t.join()方法只会使主线程(或者说调用t.join()的线程)进入等待池并等待t线程执行完毕后才会被唤醒。并不影响同一时刻处在运行状态的其他线程。
     *
     * @throws Exception
     */
    public static void method1() throws Exception{
        T1 t1=new T1();
        T2 t2=new T2();
        t1.start();
        t1.join(1000);
        t2.start();
    }

    /**
     * 利用countDownLatch，栅栏
     * countDownLatch这个类使一个线程等待其他线程各自执行完毕后再执行。
     * 是通过一个计数器来实现的，计数器的初始值是线程的数量。每当一个线程执行完毕后，计数器的值就-1，当计数器的值为0时，表示所有线程都执行完毕，然后在闭锁上等待的线程就可以恢复工作了。
     *
     * @throws Exception
     */
    public static void method2() throws Exception{
        CountDownLatch c1=new CountDownLatch(1);
        CountDownLatch c2=new CountDownLatch(1);
        Thread t1=new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    c1.await();
                    System.out.print("hello ");
                    c2.countDown();
                }catch (Exception e){
                    e.printStackTrace();
                }

            }
        });

        Thread t2=new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    c2.await();
                    System.out.print("world");
                    //c2.countDown();
                }catch (Exception e){
                    e.printStackTrace();
                }

            }
        });
        t1.start();
        t2.start();
        c1.countDown();
    }

    static class T1 extends Thread{
        @Override
        public void run() {
            System.out.print("hello ");
        }
    }

    static class T2 extends Thread{
        @Override
        public void run() {
            System.out.print("world");
        }
    }
}
